package com.chinaedu.oc.database;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import com.chinaedu.oc.util.annotation.Master;
import com.chinaedu.oc.util.annotation.Slaver;


/**
 * 定义数据源的AOP切面，通过该Service的方法名判断是应该走读库还是写库
 * 
 */
public class DataSourceAspect {

	/**
	 * 在进入Service方法之前执行
	 * 
	 * @param point
	 *            切面对象
	 */
	public void before(JoinPoint point) {
		//System.out.println("aop before进来了...");
		// 获取到当前执行的方法名
		String methodName = point.getSignature().getName();
		Class clazz = point.getSignature().getDeclaringType();
		//System.out.println("methodName:" + methodName);
		//System.out.println("clazz:" + clazz);
		try {
			if (isSlave(point)) {
				//System.out.println("slaver");
				// 标记为从库
				DBContextHolder.setDBType(DBContextHolder.DATA_SOURCE_SLAVER);
			} else {
				//System.out.println("master");
				// 标记为主库
				DBContextHolder.setDBType(DBContextHolder.DATA_SOURCE_MASTER);
			}
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 判断是否为读库
	 * 
	 * @param methodName
	 * @return
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	private Boolean isSlave(JoinPoint point) throws NoSuchMethodException, SecurityException {
		// 方法名以query、find、get开头的方法名走从库
		// return StringUtils.startsWithAny(methodName, "query", "find", "get");

		Object target = point.getTarget();
		String method = point.getSignature().getName();

		Class<?>[] classz = target.getClass().getInterfaces();

		Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes();

		Method m = classz[0].getMethod(method, parameterTypes);

		if (m != null && m.getAnnotation(Master.class) != null) {
			return false;
		}
		if (m != null && m.getAnnotation(Slaver.class) != null) {
			return true;
		}
		return false;
	}

}